#include "Acceptor.h"
#include <iostream>

using std::cout;
using std::endl;
using std::cerr;

#include <sys/socket.h>
#include <fcntl.h>
Acceptor::Acceptor(const string &ip, unsigned short port)
: _sock()
, _addr(ip, port)
{

}

Acceptor::~Acceptor()
{}

void Acceptor::ready()//执行地址端口复用\bind\listen
{
    setReuseAddr();
    setReusePort();
    setNonBlocking();
    bind();
    listen();
}

int Acceptor::accept()
{
    int fd = ::accept(_sock.fd(), nullptr, nullptr);
    if(fd == -1)
    {
        cerr << "Acceptor::accept" << endl;
        return -1;
    }
    return fd;
}
void Acceptor::setReuseAddr() 
{
    int opt = 1;
    int ret = setsockopt(_sock.fd(), SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    if(ret == -1)
    {
        cerr << "setsockopt"  << endl;
        return;
    }
} 
void Acceptor::setReusePort()
{
    int opt = 1;
    int ret = setsockopt(_sock.fd(), SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt));
    if(ret == -1)
    {
        cerr << "setsockopt"  << endl;
        return;
    }
}

void Acceptor::setNonBlocking()
{
    int flags = fcntl(_sock.fd(), F_GETFL, 0);
    if (flags == -1) {
        cerr << "fcntl F_GETFL" << endl;
        return;
    }
    flags |= O_NONBLOCK;
    int ret = fcntl(_sock.fd(), F_SETFL, flags);
    if (ret == -1) {
        cerr << "fcntl F_SETFL" << endl;
        return;
    }
}

void Acceptor::bind()
{
    int ret = ::bind(_sock.fd(), (struct sockaddr*)_addr.getAddrPtr(), sizeof(struct sockaddr));
    if(ret == -1)
    {
        perror("bind");
        return;
    }

}
void Acceptor::listen()
{
    int ret = ::listen(_sock.fd(), 128);
    if(-1 == ret)
    {
        perror("listen");
        return;
    }
    cout << "server is listening......" << endl;
}

int Acceptor::fd()
{
    return _sock.fd();
}
